#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import os
import pathlib

from common.common_models import ActionResult, SubJobDetails
from common.const import ExecuteResultEnum, SubJobStatusEnum
from common.common import output_result_file
from common.util.exec_utils import exec_overwrite_file
from tpops.gaussdb.common.const import GaussDBCode
from tpops.gaussdb.common.parse_param import tpops_parse_param_with_jsonschema
from tpops.gaussdb.common.safe_get_information import ResourceParam
from tpops.gaussdb.handle.restore.exec_restore import Restore
from tpops.gaussdb.common.log import log
from goldendb.schemas.glodendb_schemas import ActionResponse


class GaussDBRestoreService(object):
    """
    恢复任务相关接口
    """

    @staticmethod
    def allow_restore_in_local_node(req_id, job_id, sub_job_id):
        """
        功能描述：是否允许本地运行, 业务目前不需要实现, 主任务执行
        参数：
        @req_id： 请求ID
        @job_id： 主任务任务ID
        @sub_job_id： 子任务ID
        返回值：
        """
        log.info(
            f'step 1: execute allow_restore_in_local_node, req_id: {req_id}, job_id: {job_id}, sub_job_id: {sub_job_id}'
        )
        response = ActionResponse(code=ExecuteResultEnum.SUCCESS)
        output_result_file(req_id, response.dict(by_alias=True))
        log.info(f"step 1: execute AllowRestoreInLocalNode interface success")
        return True

    @staticmethod
    def restore_pre_job(req_id, job_id, sub_id, data):
        """
        功能描述：恢复前置任务, 主任务执行, 检查参数是否符合要求, 配置roach映射关系
        参数：
         @req_id： 请求ID
         @job_id： 主任务任务ID
        返回值：
        """
        log.info(f'step 3: execute restore_pre_job,req_id:{req_id} job_id:{job_id}')
        # 1、验证参数
        param_inst = ResourceParam(req_id)
        param = param_inst.get_param()
        restore_inst = Restore(req_id, job_id, sub_id, data, param)
        cache_area = restore_inst.get_cache_path()
        result = True
        try:
            result, error_code = restore_inst.restore_pre_job()
        except Exception as err:
            log.info(f"restore pre job failed, err: {err}")
            result = False
        if result:
            result_file = os.path.join(cache_area, "RestorePrerequisiteProgress")
            pathlib.Path(result_file).touch()
        else:
            result_file = os.path.join(cache_area, "RestorePrerequisiteFailProgress")
            pathlib.Path(result_file).touch()
        # 2、配置roach映射关系
        # 3、检查region 是否一致
        log.info(f'step 3: finish to execute restore_pre_job,req_id:{req_id} job_id:{job_id}')
        return True

    @staticmethod
    def restore_prerequisite_progress(req_id, job_id, sub_id, data):
        """
        功能描述：恢复前置任务进度上报
        参数：
        @req_id： 请求ID
        @job_id： 主任务任务ID
        @sub_id：子任务ID
        返回值：
        """
        log.info(
            f'start execute restore_prerequisite_job_progress, req_id: {req_id}, job_id: {job_id},  sub_id: {sub_id}')
        param_inst = ResourceParam(req_id)
        param = param_inst.get_param()
        restore_inst = Restore(req_id, job_id, sub_id, data, param)
        restore_inst.restore_prerequisite_progress()
        return True

    @staticmethod
    def restore_gen_sub_job(req_id, job_id, sub_id, json):
        """
        功能描述：划分子任务
        参数：
        @req_id： 请求ID
        @job_id： 主任务任务ID
        @sub_id：子任务ID
        @json: 任务参数
        返回值：
        """
        log.info(
            f'start execute restore_gen_sub_job, req_id: {req_id}, job_id: {job_id},  sub_id: {sub_id}')
        param_inst = ResourceParam(req_id)
        param = param_inst.get_param()
        restore_inst = Restore(req_id, job_id, sub_id, json, param)
        restore_inst.gen_sub_job()
        return True

    @staticmethod
    def restore_progress(req_id, job_id, sub_id, data):
        """
        功能描述：恢复前置任务进度上报
        参数：
        @req_id： 请求ID
        @job_id： 主任务任务ID
        @sub_id：子任务ID
        返回值：
        """
        log.info(
            f'start execute restore_prerequisite_job_progress, req_id: {req_id}, job_id: {job_id},  sub_id: {sub_id}')
        progress = SubJobDetails(taskId=job_id, subTaskId=sub_id, progress=100,
                                 taskStatus=SubJobStatusEnum.COMPLETED.value)
        output_result_file(req_id, progress.dict(by_alias=True))
        return True

    @staticmethod
    def restore_post_job(req_id, job_id, sub_id, data):
        """
        功能描述：恢复前置任务进度上报
        参数：
        @req_id： 请求ID
        @job_id： 主任务任务ID
        @sub_id：子任务ID
        返回值：
        """
        log.info(f"Start to execute the restore_post_job task.")
        output = ActionResult(code=ExecuteResultEnum.SUCCESS)
        try:
            body_param = tpops_parse_param_with_jsonschema(req_id)
        except Exception as err_code:
            raise Exception(f"Failed to parse job param file for {err_code}") from err_code
        if not body_param:
            raise Exception(f"Failed to parse job param file is none")
        restore_inst = Restore(req_id, job_id, sub_id, data, body_param)
        result = restore_inst.do_post()
        if not result:
            output.code = ExecuteResultEnum.INTERNAL_ERROR
        exec_overwrite_file(req_id, output.dict(by_alias=True))
        return True

    @staticmethod
    def restore_post_job_progress(req_id, job_id, sub_id, data):
        """
        功能描述：恢复前置任务进度上报
        参数：
        @req_id： 请求ID
        @job_id： 主任务任务ID
        @sub_id：子任务ID
        返回值：
        """
        log.info(
            f'start execute restore_post_job_progress, req_id: {req_id}, job_id: {job_id},  sub_id: {sub_id}')
        progress_info = SubJobDetails(taskId=job_id, subTaskId=sub_id, taskStatus=SubJobStatusEnum.COMPLETED.value,
                                      logDetail=[], progress=100, dataSize=0, speed=0, extendInfo=None)
        output_result_file(req_id, progress_info.dict(by_alias=True))
        return True

    @staticmethod
    def set_error_response(response):
        response.code = GaussDBCode.FAILED.value
        response.body_err = GaussDBCode.FAILED.value
